﻿// <copyright file="StorageBlockInfoTable.cs" company="Sinclair Community College">
// Copyright 2010 Sinclair Community College
// </copyright>
// <originalAuthor>Patrick S. Seymour (patrick.seymour@gmail.com)</originalAuthor>

namespace SinclairCC.AppV
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    public class StorageBlockInfoTable : System.Collections.ObjectModel.KeyedCollection<uint, StorageBlockInfo>
    {
        /// <summary>
        /// Initializes a new instance of the StorageBlockInfoTable class.
        /// </summary>
        public StorageBlockInfoTable(System.IO.BinaryReader fileReader)
        {
            this.ReadContainer2(fileReader);
        }
        
        protected override uint GetKeyForItem(StorageBlockInfo item)
        {
            return item.AllocationIndex;
        }
        
        /// <summary>
        /// Reads the actual data for this container from the file.
        /// </summary>
        protected void ReadContainer2(System.IO.BinaryReader fileReader)
        {
            do
            {
                uint allocIndex = fileReader.ReadUInt32();
                uint numBlocks = fileReader.ReadUInt32();

                if (!((allocIndex == 0) && (numBlocks == 0)))
                {
                    if (allocIndex == (uint)SpecialFlags.SOFTFS_END_OF_BLOCK)
                    {
                        if (numBlocks <= 0)
                        {
                            // There are more StorageBlockInfo entries available for this container
                            // which reside in another storage block. The storage block index is 
                            // specified here by BlockCount. The actual starting offset can be
                            // obtained with StorageBlockInfo.GetOffset();
                            //
                            // You need to look at the bottom of figure 6 in the specification.
                            Console.WriteLine("You have more storage block infos somewhere else.");
                            //Console.WriteLine("Offset: {0}", stBlock.GetOffset(512, 4096));
                        }
                        else
                        { // We have processed all the StorageBlockInfo entries for this container.
                            Console.WriteLine("You're done processing StorageBlockInfo structures.");
                            break;
                        }
                    }
                    else
                    { // This is a valid StorageBlockInfo structure.
                        if (this.Contains(allocIndex))
                        {
                            Console.WriteLine();
                            Console.WriteLine("Trying to add a StorageBlockInfo with allocation index of {0} and a block count of {1}.", allocIndex, numBlocks);
                            Console.WriteLine("The allocation index already exists in the table with a block count of {0}.", this[allocIndex].BlockCount);
                            Console.WriteLine();
                        }
                        else
                        {
                            this.Add(new StorageBlockInfo(allocIndex, numBlocks));
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            while (true);
        }

        /*
        protected void ReadContainer(System.IO.BinaryReader fileReader)
        {
            StorageBlockInfo stBlock;
            do
            {
                uint allocIndex = fileReader.ReadUInt32();
                uint numBlocks = fileReader.ReadUInt32();

                stBlock = new StorageBlockInfo(allocIndex, numBlocks);
                if (stBlock.AllocationIndex == (uint)SpecialFlags.SOFTFS_END_OF_BLOCK)
                {
                    if (stBlock.BlockCount > 0)
                    {
                        // There are more StorageBlockInfo entries available for this container
                        // which reside in another storage block. The storage block index is 
                        // specified here by BlockCount. The actual starting offset can be
                        // obtained with StorageBlockInfo.GetOffset();
                        //
                        // You need to look at the bottom of figure 6 in the specification.
                        Console.WriteLine("You have more storage block infos somewhere else.");
                        Console.WriteLine("Offset: {0}", stBlock.GetOffset(512, 4096));
                    }
                    else
                    {
                        // We have processed all of the StorageBlockInfo entries of this container.
                        Console.WriteLine("You're done processing StorageBlockInfo structures.");
                        break;
                    }
                }
                else
                {
                    if (this.Contains(stBlock.AllocationIndex))
                    {
                        Console.WriteLine();
                        ConsoleColor foreColor = Console.ForegroundColor;
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("Trying to add a StorageBlockInfo with allocation index of {0} and a block count of {1}.", stBlock.AllocationIndex, stBlock.BlockCount);
                        Console.WriteLine("The allocation index already exists in the table with a block count of {0}.", this[stBlock.AllocationIndex].BlockCount);
                        Console.ForegroundColor = foreColor;
                        Console.WriteLine();
                    }
                    else
                    {
                        if (!((stBlock.BlockCount == 0) && (stBlock.AllocationIndex == 0)))
                        {
                            this.Add(stBlock);
                        }
                    }
                }
            }
            while (!((stBlock.BlockCount == 0) && (stBlock.AllocationIndex == 0)));
        }
        */

    }
}
